#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <setjmp.h>
#include <time.h>
#include <signal.h>       /* for signal */  
#include <execinfo.h>     /* for backtrace() */  
#include <fcntl.h>
#include <unistd.h>

static void            sig_usr1(int), sig_alrm(int);
static sigjmp_buf        jmpbuf;
static volatile sig_atomic_t     canjump;

int main(void)
{
	if (signal(SIGUSR1, sig_usr1) == SIG_ERR)
		printf("signal(SIGUSR1) error\n");

	if (signal(SIGALRM, sig_alrm) == SIG_ERR)
		printf("signal(SIGALRM) error\n");

	printf("starting main: ");

	if (sigsetjmp(jmpbuf, 1))
	{
		printf("ending main: ");
		exit(0);
	}
	canjump = 1;    /* now sigsetjmp() is OK */

	for(; ;)
		pause();
}

static void sig_usr1(int signo)
{    
	time_t starttime;

	if (canjump == 0)
		return;        /* unexpected signal, ignore */

	printf("starting sig_usr1: ");
	alarm(3);        /* SIGALRM in 3 seconds */
	starttime = time(NULL);
	for(; ;)        /* busy wait for 5 seconds */
		if (time(NULL) > starttime + 5)
			break;
	printf("finishing sig_usr1: ");

	canjump = 0;
	siglongjmp(jmpbuf, 1);    /* jump back to main, don't return */
}

static void sig_alrm(int signo)
{
	printf("in sig_alrm: ");
}
